package main

import (
	"fmt"
	"sync"
	"time"
)

func printIntValue(value int, cond *sync.Cond) {
	cond.L.Lock()
	if value < 5 {
		//value小于5时，进入等待状态
		cond.Wait()
	}
	//大于5的正常输出
	fmt.Println(value)
	cond.L.Unlock()
}

func main() {

	//条件等待
	mutex := sync.Mutex{}
	//使用锁创建一个条件等待
	cond := sync.NewCond(&mutex)

	for i := 0; i < 10; i++ {
		go printIntValue(i, cond)
	}

	time.Sleep(time.Second * 1)
	cond.Signal() //解除一个阻塞
	time.Sleep(time.Second * 1)
	cond.Broadcast() //解除全部阻塞
	time.Sleep(time.Second * 1)
}

/*
3)使用条件变量实现线程同步
go语言提供了条件变量sync.Cond，sync.Cond方法如下：

Wait，Signal，Broadcast。
Wait添加一个计数，也就是添加一个阻塞的goroutine。
Signal解除一个goroutine的阻塞，计数减一。
Broadcast接触所有wait goroutine的阻塞。

解除一个阻塞，输出0，解除全部阻塞，输出1 2 3 4;
go语言多线程支持全局唯一性操作，即一个只允许goruntine调用一次，重复调用无效。
go语言还支持sync.WaitGroup实现多个线程同步的操作。

*/
